/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */



package com.android1.amarena2d.engine;

import com.android1.amarena2d.commons.collections.FixedSizeStagingList;
import com.android1.amarena2d.engine.collision.Collision;
import com.android1.amarena2d.engine.collision.CollisionVolume;
import com.android1.amarena2d.nodes.behavior.delegates.CollisionDelegate;

import java.util.ArrayList;

//todo collisionGroups / layer ?
public class CollisionManagerImpl extends EngineObject implements CollisionManager {

    //todo improve me
    ArrayList<CollisionDelegate> collisionDelegates;
    FixedSizeStagingList<CollisionDelegate> collisionDelegates2;

    public CollisionManagerImpl() {
        this.collisionDelegates = new ArrayList<CollisionDelegate>();
        this.collisionDelegates2 = new FixedSizeStagingList<CollisionDelegate>(engine.getConfig().get(Config.COLLISION_MAX_OBJECTS));

    }

    @Override
    public void register(CollisionDelegate collisionDelegate) {
        collisionDelegates.add(collisionDelegate);
//        collisionDelegates.ad
    }

    @Override
    public void unregister(CollisionDelegate collisionDelegate) {
        collisionDelegates.remove(collisionDelegate);
    }

    public void tick() {

        for (int i = 0; i < collisionDelegates.size(); i++) {
            CollisionDelegate collisionDelegate = collisionDelegates.get(i);

            //Only active objects will check themself against other collision objects
            if (collisionDelegate.getCheckBehaviour() != Collision.CheckBehaviour.Passive
                    && collisionDelegate.isActive()) {

                //Will save the last position before a collision.
                if (!checkCollisions(collisionDelegate)) {
                    collisionDelegate.saveLastPos();
                }
            }
        }
    }

    private boolean checkCollisions(final CollisionDelegate collisionDelegate) {

        final CollisionVolume volume = collisionDelegate.getVolume();
        boolean hasCollision = false;

        for (int i = 0; i < collisionDelegates.size(); i++) {

            final CollisionDelegate otherCollisionDelegate = collisionDelegates.get(i);

            if (collisionDelegate != otherCollisionDelegate && otherCollisionDelegate.isActive()) {
                final CollisionVolume otherVolume = otherCollisionDelegate.getVolume();

                if (volume.intersects(otherVolume)) {
                    
                    if (collisionDelegate.isNotifyOnCollision())
                        collisionDelegate.onCollision(otherCollisionDelegate);

                    if (otherCollisionDelegate.isNotifyOnCollision())
                        otherCollisionDelegate.onCollision(collisionDelegate);

                    if (!collisionDelegate.isAllowMultipleCollisionsPerTick())
                        return true;
                    else
                        hasCollision = true;
                }
            }
        }
        return hasCollision;
    }


}